home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / bplus25a.zip / CPLUS.C < prev    next >
Text File  |  1990-12-30  |  40KB  |  1,049 lines

  1. /********************************************************************/
  2. /*                                                                  */
  3. /*             BPLUS file indexing program - Version 2.5            */
  4. /*                                                                  */
  5. /*                      A "shareware program"                       */
  6. /*                                                                  */
  7. /*                                                                  */
  8. /*                    Copyright (C) 1987-1990 by                    */
  9. /*                                                                  */
  10. /*                      Hunter and Associates                       */
  11. /*                      7900 Edgewater Drive                        */
  12. /*                      Wilsonville, Oregon  97070                  */
  13. /*                      (503) 694 - 1449                            */
  14. /*                                                                  */
  15. /********************************************************************/
  16.  
  17.  
  18. #include <stdio.h>
  19. #include <fcntl.h>
  20. #include <io.h>
  21. #include <process.h>
  22. #include <sys\types.h>            /*  delete this line for Turbo C  */
  23. #include <sys\stat.h>
  24. #include <string.h>
  25. #include "bplus.h"
  26.  
  27.  
  28. /*  macros, constants, data types  */
  29.  
  30. #define  NULLREC      (-1L)  /* special value for RECPOS variable */
  31. #define  FREE_BLOCK   (-2)   /* designates a free block in index file */
  32.         /* the address of an entry in a block */
  33. #define  ENT_ADR(pb,off)  ((ENTRY*)((char*)((pb)->entries) + off))
  34.         /* the size of an entry */
  35. #define  ENT_SIZE(pe)     strlen((pe)->key) + 1 + 2 * sizeof(RECPOS)
  36.         /* the cache changed indicator */
  37. #define  BUFDIRTY(j)      (mci->cache[j].dirty)
  38.         /* the index file handle for memblock j */
  39. #define  BUFHANDLE(j)     (mci->cache[j].handle)
  40.         /* memory cache block j */
  41. #define  BUFBLOCK(j)      (mci->cache[j].mb)
  42.         /* number of times cache blk j is referenced */
  43. #define  BUFCOUNT(j)      (mci->cache[j].count)
  44.         /* address of current block for level j */
  45. #define  CB(j)            (pci->pos[j].cblock)
  46.         /* offset of current block for level j */
  47. #define  CO(j)            (pci->pos[j].coffset)
  48. #define  TRUE             1
  49. #define  FALSE            0
  50.  
  51.  
  52. /*  declare some global variables  */
  53.  
  54. IX_DESC      *pci;                       /* pointer to index descriptor   */
  55. IX_BUFFER    bt_buffer;                  /* memory cache for index blocks */
  56. IX_BUFFER    *mci = &bt_buffer;          /* pointer to cache index blocks */
  57. BLOCK        *block_ptr;                 /* pointer to index record block */
  58. BLOCK        *spare_block;               /* pointer to spare index block  */
  59. int          cache_ptr = 0;              /* index to cache memory pool    */
  60. int          cache_init = 0;             /* 1 when cache is initilized    */
  61. int          split_size = IXB_SPACE;     /* split block when greater than */
  62. int          comb_size  = (IXB_SPACE/2); /* combine blocks when less than */
  63.  
  64. /* #define memmove     memcpy */    /* Use this macro for MicroSoft C 4.0 */
  65.  
  66. /* list all function prototypes */
  67. void pascal error(int, long);
  68. void pascal read_if(long, char *, int);
  69. void pascal write_if(int, long, char *, int);
  70. int  pascal creat_if(char *);
  71. int  pascal open_if(char *);
  72. void pascal reset_buffers(IX_DESC *);
  73. void pascal close_if(int);
  74. void pascal update_block(void);
  75. void pascal init_cache(void);
  76. int  pascal find_cache(RECPOS);
  77. int  pascal new_cache(void);
  78. void pascal load_cache(RECPOS);
  79. void pascal get_cache(RECPOS);
  80. void pascal retrieve_block(int, RECPOS);
  81. int  pascal prev_entry(int);
  82. int  pascal next_entry(int);
  83. void pascal copy_entry(ENTRY *, ENTRY *);
  84. int  pascal scan_blk(int);
  85. int  pascal last_entry(void);
  86. void pascal write_free( RECPOS, BLOCK *);
  87. RECPOS pascal get_free(void);
  88. int  pascal find_block(ENTRY *, int *, int *);
  89. void pascal movedown(BLOCK *, int, int);
  90. void pascal moveup(BLOCK *, int, int);
  91. void pascal ins_block(BLOCK *, ENTRY *, int);
  92. void pascal del_block(BLOCK *, int);
  93. void pascal split(int, ENTRY *, ENTRY *);
  94. void pascal ins_level(int, ENTRY *);
  95. int  pascal insert_ix(ENTRY *, IX_DESC *);
  96. int  pascal find_ix(ENTRY *, IX_DESC *, int);
  97. int  pascal combineblk(RECPOS, int);
  98. void pascal replace_entry(ENTRY *);
  99.  
  100.  
  101. /*  file I/O for B-PLUS module  */
  102.  
  103. void pascal error(j, l)               /* print file error messages */
  104.   int j;                              /* error number */
  105.   long l;                             /* current file position */
  106.   {
  107.     static char *msg[3] = {"ERROR - CANNOT OPEN/CLOSE FILE",
  108.                            "ERROR WHILE READING FILE",
  109.                            "ERROR WHILE WRITING FILE"};
  110.     printf("\n  %s - Record Number %ld\n", msg[j], l);
  111.     exit(1);                  /* delete this line to not halt program */
  112.                               /* and call your error handlng routine */
  113.   } /* error */
  114.  
  115.  
  116. void pascal read_if(start, buf, nwrt)    /* read pci index file */
  117.   long start;                            /* file read position */
  118.   char *buf;                             /* data holding buffer */
  119.   int nwrt;                              /* number bytes to read */
  120.   {
  121.     long err;
  122.           /* seek to read position in current index file */
  123.     err = start - lseek(pci->ixfile, start, SEEK_SET);
  124.          /* if no error read an index file block */
  125.     if (err == 0) err = nwrt - read(pci->ixfile, buf, nwrt);
  126.          /* call error routine if number bytes read != nwrt */
  127.     if (err != 0) error(1, start);
  128.   } /* read_if */
  129.  
  130.  
  131. void pascal write_if(handle, start, buf, nwrt)   /* write index record */
  132.   int handle;                        /* write to this file handle */
  133.   long start;                        /* write to this position in file */
  134.   char *buf;                         /* write data from this buffer */
  135.   int nwrt;                          /* write this many bytes of data */
  136.   {
  137.     long err;
  138.          /* seek to file write position */
  139.     err = start - lseek(handle, start, SEEK_SET);
  140.          /* if no error write index block block */
  141.     if (err == 0) err = nwrt - write(handle, buf, nwrt);
  142.          /* call error routine if number bytes written != nwrt */
  143.     if (err != 0) error(2, start);
  144.   } /* write_if */
  145.  
  146.  
  147. int pascal creat_if(fn)               /* make a new index file */
  148.   char *fn;                           /* name and path of file */
  149.   {
  150.     int   ret;
  151.     ret = open(fn,O_RDWR|O_CREAT|O_TRUNC|O_BINARY,S_IWRITE);
  152.     if (ret  < 0) error(0,0L);        /* there was an error if ret < 0 */
  153.     return (ret);
  154.   } /* creat_if */
  155.  
  156.  
  157. int pascal open_if(fn)                /* open an existing index file */
  158.   char *fn;                           /* path and name of index file */
  159.   {
  160.     int  ret;
  161.     ret = open(fn,O_RDWR|O_BINARY);
  162.     if (ret < 1) error(0,0L);         /* there was an error is ret < 1 */
  163.     return (ret);
  164.   } /* open_if */
  165.  
  166.  
  167. void pascal close_if(handle)          /* close an open index file */
  168.   int handle;                         /* with this file handle    */
  169.   {
  170.     if(close(handle) < 0)  error(2,0L);
  171.   } /*  close_if */
  172.  
  173.  
  174. int cdecl open_index(name, pix, dup)  /* open and initilize index file */
  175.   char *name;                         /* path and name of index file */
  176.   IX_DESC *pix;                       /* pointer to index descriptor */
  177.   int dup;                            /* allow duplicate keys if != 0 */
  178.   {
  179.     pci = pix;                        /* pci is global index descriptor */
  180.     pci->ixfile = open_if(name);      /* file handle */
  181.     pci->duplicate = dup;             /* set duplicate keys flag */
  182.     pci->root_dirty = FALSE;
  183.      /* read root descriptor for index */
  184.     read_if(0L,(char *)&(pix->root), (sizeof(BLOCK) + sizeof(IX_DISK)));
  185.     if (!cache_init)                   /* if cache not initilized */
  186.       {
  187.         init_cache();                  /* initilize cache memory */
  188.         cache_init = 1;                /* but only once */
  189.       }
  190.     return ( IX_OK );
  191.   } /* open_index */
  192.  
  193.  
  194. void cdecl